import { useState, useEffect, useRef } from 'react'
import { Result } from 'utils/http'
import { Pagination, PaginationState, PaginationParameter, } from './entity'
import Taro from '@tarojs/taro'
import {produce} from 'immer'

export type PaginationAPIFunc<T, P> = (parameter: P) => Promise<Result<Pagination<T>>>

export interface FetchResult<T> {
  loading: boolean,
  errMsg: string,
  data: T
}

export type API<T> = () => {
  api: PaginationAPIFunc<T, PaginationParameter>,
  parameter: PaginationParameter
}

const paginationState: PaginationState<any> = {
  list: [],
  total: 0,
  current: 1,
  pageSize: 10,
  lastPage: false,
  increasing: false,
  refreshing: false,
  loading: true,
  errMsg: '',
}

export default function usePagenation<T>(createApi: API<T>) {
  const {api, parameter} = createApi()
  const parameterRef = useRef(parameter)
  const [state, setState] = useState<PaginationState<T>>(paginationState)
  const {refreshing, current, increasing, loading, lastPage} = state

  const fetchList = () => {
    return api(parameterRef.current).then(res => {
      const {list = [], ...pagination} = res.data

      setState({
        list: pagination.current == 1 ? list : state.list.concat(list),
        ...pagination,
        loading: false,
        refreshing: false,
        increasing: false,
        errMsg: ''
      })
      Taro.stopPullDownRefresh()
    })
      .catch((err) => {
        console.log(err)
      })
  }

  useEffect(() => {
    loading && setParameter({ current: 1 })
  }, [loading]);

  useEffect(() => {
    refreshing && setParameter({ current: 1 })
  }, [refreshing]);

  useEffect(() => {
    if (increasing) {
      if (lastPage) {
        setState(state => produce(state, df => {
          df.increasing = false
        }))
        return
      }
      setParameter({current: current + 1})
    }
  }, [increasing])

  function setParameter(option: PaginationParameter) {
    parameterRef.current = {...parameterRef.current, ...option}
    fetchList()
  }

  function setRefreshing(refreshing: boolean) {
    setState((state) => produce(state, df => {
      df.refreshing = refreshing
    }))
  }

  function setIncreasing(inc: boolean) {
    if (lastPage) return
    setState((state) => produce(state, df => {
      df.increasing = inc
    }))
  }

  return {
    ...state,
    setLoading: (loading: boolean) => {
      const producer = produce((df) => {
        df.loading = loading
      })
      setState((state) => producer(state))
    },
    setIncreasing,
    setRefreshing,
    setParameter,
    resetParameter: () => setParameter(parameter),
    /* 更新 list 中的某条数据 */
    update: (item: T, index: number) => {
      setState(state => produce<any>(state, df => {
        df.list[index] = {...item}
      }))
    },
    push: (item: T) => setState(state => produce<any>(state, df => {
      df.list.push(item)
      df.total += 1
    })),
    unshift: (item: T) => setState(state => produce<any>(state, df => {
      df.list.unshift(item)
      df.total += 1
    })),
    pop: () => setState(state => produce<any>(state, df => {
      if (df.list.length > 0) {
        df.list.pop()
        df.total -= 1
      }
    })),
    shift: () => setState(state => produce<any>(state, df => {
      df.list.shift()
      df.total -= 1
    })),
    splice: (start: number, count: number) => setState(state => produce<any>(state, df => {
      if (df.list.length > 0) {
        df.list.splice(start, count)
        df.total -= count
      }
    }))
  }
}
